package cn.lhn.ridersclub.service;

import cn.lhn.ridersclub.dto.*;
import cn.lhn.ridersclub.entity.*;
import cn.lhn.ridersclub.mapper.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
public class PaperServiceImpl implements PaperService {

    private final PaperMapper paperMapper;

    private final CommentMapper commentMapper;

    private final CommentSupportMapper commentSupportMapper;

    private final SupportMapper supportMapper;

    private final ClubMapper clubMapper;

    private final AccountMapper accountMapper;

    private final CommentService commentService;

    private final ClubService clubService;

    private final SupportService supportService;

    private final GradeService gradeService;

    private final AccountFollowMapper accountFollowMapper;

    private final ClubFollowService clubFollowService;

    private final HistoryMapper historyMapper;

    public PaperServiceImpl(PaperMapper paperMapper, CommentMapper commentMapper, CommentSupportMapper commentSupportMapper, SupportMapper supportMapper, ClubMapper clubMapper, AccountMapper accountMapper, CommentService commentService, ClubService clubService, SupportService supportService, GradeService gradeService, AccountFollowMapper accountFollowMapper, ClubFollowService clubFollowService, HistoryMapper historyMapper) {
        this.paperMapper = paperMapper;
        this.commentMapper = commentMapper;
        this.commentSupportMapper = commentSupportMapper;
        this.supportMapper = supportMapper;
        this.clubMapper = clubMapper;
        this.accountMapper = accountMapper;
        this.commentService = commentService;
        this.clubService = clubService;
        this.supportService = supportService;
        this.gradeService = gradeService;
        this.accountFollowMapper = accountFollowMapper;
        this.clubFollowService = clubFollowService;
        this.historyMapper = historyMapper;
    }

    @Override
    public void addPaper(String title, String connect, Long clubId, Long accountId) {

        //  判断账号是否存在
        Account account = accountMapper.selectById(accountId);
        if (account == null) {
            throw new RuntimeException("账号不存在");
        }

        //  判断车友圈是否存在
        Club club = clubMapper.selectById(clubId);
        if (club == null) {
            throw new RuntimeException("车友圈不存在");
        }

        //  插入数据
        int i = paperMapper.insert(new Paper(0L, title, connect, clubId, accountId, LocalDateTime.now()));
        if (i == 0) {
            throw new RuntimeException("添加失败");
        }
    }

    @Override
    public void deletePaper(Long paperId, Long accountId) {

        //  删除文章
        QueryWrapper<Paper> qwp = new QueryWrapper<>();
        qwp.eq("id", paperId);
        qwp.eq("account_id", accountId);
        int i = paperMapper.delete(qwp);
        if (i == 0) {
            throw new RuntimeException("删除失败");
        }

        //  删除评论
        QueryWrapper<Comment> qwc = new QueryWrapper<>();
        qwc.eq("paper_id", paperId);
        i = commentMapper.delete(qwc);

        //  删除点赞
        QueryWrapper<Support> qws = new QueryWrapper<>();
        qws.eq("paper_id", paperId);
        i = supportMapper.delete(qws);
    }

    @Override
    public PaperInfoDto getPaperById(Long paperId) {
        Paper paper = paperMapper.selectById(paperId);
        return toPaperInfoDto(paper);
    }

    @Override
    public List<PaperCardDto> getByKeyword(String keyword, Long startId) {
        //  关键词查询文章列表
        List<Paper> paperList = paperMapper.listByKeyword(keyword, startId);
        List<PaperCardDto> l = new ArrayList<>();
        for (Paper paper : paperList) {
            l.add(toPaperCardDto(paper));
        }
        return l;
    }

    @Override
    public List<PaperCardDto> getPapers(Long accountId, Long startId) {
        List<Paper> paperList = paperMapper.listByAccountId(accountId, startId);
        List<PaperCardDto> l = new ArrayList<>();
        for (Paper paper : paperList) {
            l.add(toPaperCardDto(paper));
        }
        return l;
    }

    @Override
    public List<PaperCardDto> getPapers() {
        List<Paper> paperList = paperMapper.listRandom();
        List<PaperCardDto> l = new ArrayList<>();
        for (Paper paper : paperList) {
            l.add(toPaperCardDto(paper));
        }
        return l;
    }

    @Override
    public List<PaperCardDto> getPapersByClubId(Long clubId, Long startId) {
        List<Paper> paperList = paperMapper.listByClubId(clubId, startId);
        List<PaperCardDto> l = new ArrayList<>();
        for (Paper paper : paperList) {
            l.add(toPaperCardDto(paper));
        }
        return l;
    }

    @Override
    public Long getPaperCount(Long accountId) {
        QueryWrapper<Paper> qw = new QueryWrapper<>();
        qw.eq("account_id", accountId);
        return paperMapper.selectCount(qw);
    }

    @Override
    public PaperCardDto getLastPaper(Long accountId) {
        return toPaperCardDto(paperMapper.getLastPaper(accountId));
    }

    @Override
    public CommentDto getLastCommentForPaper(Long accountId, Long paperId) {

        Comment comment = commentMapper.getLastCommentForPaper(accountId, paperId);
        if (comment == null) {
            return null;
        }

        String accountName = accountMapper.getNicknameById(comment.getAccountId());

        return CommentDto
                .builder()
                .id(comment.getId())
                .accountId(comment.getAccountId())
                .accountName(accountName)
                .content(comment.getContent())
                .time(comment.getCreateTime())
                .supportCount(commentSupportMapper.getCommentSupportCount(comment.getId()))
                .commentCount(commentService.subjectCommentCount(comment.getId()))
                .build();
    }

    @Override
    public void addHistory(Long paperId, Long accountId) {

        Paper paper = paperMapper.selectById(paperId);
        if (paper == null) {
            throw new RuntimeException("文章不存在");
        }

        Account account = accountMapper.selectById(accountId);
        if (account == null) {
            throw new RuntimeException("账号不存在");
        }

        QueryWrapper<History> qw = new QueryWrapper<>();
        qw.eq("paper_id", paperId);
        qw.eq("account_id", accountId);
        History history = historyMapper.selectOne(qw);
        if (history == null) {
            history = new History(null, paperId, accountId, LocalDateTime.now());
            historyMapper.insert(history);
        }
        else {
            history.setCreateTime(LocalDateTime.now());
            historyMapper.updateById(history);
        }
    }

    @Override
    public List<HistoryDto> listHistory(Long accountId, Long startId) {
        List<History> list = historyMapper.listHistory(accountId, startId);
        List<HistoryDto> l = new ArrayList<>();
        for (History history : list) {

            Paper paper = paperMapper.selectById(history.getPaperId());
            if (paper == null) {
                continue;
            }

            HistoryDto dto = HistoryDto
                    .builder()
                    .id(history.getId())
                    .paperId(paper.getId())
                    .authorId(paper.getAccountId())
                    .authorName(accountMapper.getNicknameById(paper.getAccountId()))
                    .title(paper.getTitle())
                    .time(history.getCreateTime())
                    .build();
            l.add(dto);
        }
        return l;
    }

    /**
     * 封装文章DTO列表
     */
    private List<PaperInfoDto> toPaperInfoDtoList(List<Paper> paperList) {

        List<PaperInfoDto> list = new ArrayList<>();

        for (Paper paper : paperList) {
            list.add(toPaperInfoDto(paper));
        }

        return list;
    }

    private PaperInfoDto toPaperInfoDto(Paper paper) {
        if (paper == null) {
            return null;
        }
        String clubName = clubMapper.getClubName(paper.getClubId());
        Long fansCount = clubFollowService.getFansCount(paper.getClubId());
        String authorName = accountMapper.getNicknameById(paper.getAccountId());
        Long supportCount = supportService.getSupportCount(paper.getId());
        Long commentCount = commentService.getCommentCount(paper.getId());

        return PaperInfoDto
                .builder()
                .id(paper.getId())
                .clubId(paper.getClubId())
                .clubName(clubName)
                .fansCount(fansCount)
                .authorId(paper.getAccountId())
                .authorName(authorName)
                .time(paper.getCreateTime())
                .title(paper.getTitle())
                .content(paper.getConnect())
                .supportCount(supportCount)
                .commentCount(commentCount)
                .build();
    }


    public AccountDto toAccountDto(Account account) {

        //  等级
        Grade grade = gradeService.getGrade(account.getId());
        Long maxGradeValue = gradeService.getMaxGradeValue(grade.getGrade());

        //  文章输数量
        Long paperCount = getPaperCount(account.getId());

        //  关注数和粉丝数

        QueryWrapper<AccountFollow> qw = new QueryWrapper<>();
        qw.eq("fans_id", account.getId());
        Long followCount = accountFollowMapper.selectCount(qw);

        qw = new QueryWrapper<>();
        qw.eq("account_id", account.getId());
        Long fansCount = accountFollowMapper.selectCount(qw);

        return AccountDto
                .builder()
                .id(account.getId())
                .nickname(account.getNickname())
                .gender(account.getGender())
                .profile(account.getProfile())
                .birth(account.getBirth())
                .createTime(account.getCreateTime())
                .grade(grade.getGrade())
                .currentGradeValue(grade.getCurrentGradeValue())
                .maxGradeValue(maxGradeValue)
                .paperCount(paperCount)
                .followCount(followCount)
                .fansCount(fansCount)
                .build();
    }

    public PaperCardDto toPaperCardDto(Paper paper) {
        if (paper == null) {
            return null;
        }

        String authorName = accountMapper.getNicknameById(paper.getAccountId());
        Long supportCount = supportService.getSupportCount(paper.getId());
        Long commentCount = commentService.getCommentCount(paper.getId());

        String clubName = clubMapper.getClubName(paper.getClubId());

        Comment comment = commentService.getMostHotComment(paper.getId());
        Long commentId = 0L;
        Long commentSupportCount = 0L;
        String commentAccountName = "";
        String commentContent = "";
        if (comment != null) {
            commentId = comment.getId();
             commentSupportCount = commentSupportMapper.getCommentSupportCount(comment.getId());
             commentAccountName = accountMapper.getNicknameById(comment.getAccountId());
            commentContent = comment.getContent();
        }

        return PaperCardDto
                .builder()
                .id(paper.getId())
                .authorId(paper.getAccountId())
                .authorName(authorName)
                .title(paper.getTitle())
                .content(paper.getConnect())
                .supportCount(supportCount)
                .commentCount(commentCount)
                .time(paper.getCreateTime())
                .clubId(paper.getClubId())
                .clubName(clubName)
                .commentId(commentId)
                .commentSupportCount(commentSupportCount)
                .commentAccountName(commentAccountName)
                .commentContent(commentContent)
                .build();
    }
}
